package com.yfp.operation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageInfo;
import com.yfp.common.core.utils.PageUtils;
import com.yfp.common.core.web.page.TableDataInfo;
import com.yfp.operation.domain.*;
import com.yfp.operation.domain.dto.*;
import com.yfp.operation.domain.vo.*;
import com.yfp.operation.service.*;
import com.yfp.operation.domain.*;
import com.yfp.operation.domain.dto.*;
import com.yfp.operation.domain.vo.*;
import com.yfp.operation.service.*;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class StatisticsAdminServiceImpl implements StatisticsAdminService {

    @Resource
    private MarCouponPackShopService marCouponPackShopService;

    @Resource
    private OrderListService orderListService;
    @Resource
    private PositionService positionService;
    @Resource
    private MachineService machineService;
    @Resource
    private DeviceComboPlanNumService deviceComboPlanNumService;
    @Resource
    private ClientService clientService;

    @Override
    public TableDataInfo<PackageSalesDataVO> getPackageSalesDataList(PackageSalesDataDTO packStatisticsReq) {
        MarCouponPackShop marCouponPackShop = new MarCouponPackShop();
        marCouponPackShop.setPackName(packStatisticsReq.getPackName());
        marCouponPackShop.setCityName(packStatisticsReq.getCityName());

        PageUtils.startPage();
        List<MarCouponPackShop> marCouponPackShops = marCouponPackShopService.list(marCouponPackShop);
        long total = new PageInfo(marCouponPackShops).getTotal();

        List<PackageSalesDataVO> list = marCouponPackShops.stream().map(entity -> {
            PackageSalesDataVO packStatisticsVO = new PackageSalesDataVO();
            packStatisticsVO.setPackId(entity.getId());
            packStatisticsVO.setPackName(entity.getPackName());
            packStatisticsVO.setTotalCopiesDistributed(entity.getPackNum());

            return packStatisticsVO;
        }).toList();

        List<Long> packIds = list.stream().map(PackageSalesDataVO::getPackId).toList();
        List<OrderListDO> orderListDOS = orderListService.listPackStatisticsByPackIds(packStatisticsReq, packIds);
        // 根据套餐id分组，并统计数量
        list.forEach(entity -> {
            List<OrderListDO> orderListDOList = orderListDOS.stream().filter(orderListDO -> StrUtil.equals(orderListDO.getComboId(), entity.getPackId().toString())).toList();
            entity.setSoldCopies(Long.valueOf(orderListDOList.size()));
            entity.setUnsoldCopies(entity.getTotalCopiesDistributed() - entity.getSoldCopies());
            entity.setSalesRate(NumberUtil.mul(NumberUtil.div(entity.getSoldCopies(), entity.getTotalCopiesDistributed()), 100));
            entity.setTotalSalesAmount(orderListDOList.stream().map(item -> NumberUtil.toBigDecimal(item.getAmt())).reduce(BigDecimal.ZERO, BigDecimal::add));
        });

        TableDataInfo<PackageSalesDataVO> dataTable = PageUtils.getDataTable(list);
        dataTable.setTotal(total);
        return dataTable;
    }

    @Override
    public List<PackageSalesDataVO> getPackageSalesDataListExport(PackageSalesDataDTO packStatisticsReq) {
        MarCouponPackShop marCouponPackShop = new MarCouponPackShop();
        marCouponPackShop.setPackName(packStatisticsReq.getPackName());
        marCouponPackShop.setCityName(packStatisticsReq.getCityName());

        List<MarCouponPackShop> marCouponPackShops = marCouponPackShopService.list(marCouponPackShop);

        List<PackageSalesDataVO> list = marCouponPackShops.stream().map(entity -> {
            PackageSalesDataVO packStatisticsVO = new PackageSalesDataVO();
            packStatisticsVO.setPackId(entity.getId());
            packStatisticsVO.setPackName(entity.getPackName());
            packStatisticsVO.setTotalCopiesDistributed(entity.getPackNum());

            return packStatisticsVO;
        }).toList();

        List<Long> packIds = list.stream().map(PackageSalesDataVO::getPackId).toList();
        List<OrderListDO> orderListDOS = orderListService.listPackStatisticsByPackIds(packStatisticsReq, packIds);
        // 根据套餐id分组，并统计数量
        list.forEach(entity -> {
            List<OrderListDO> orderListDOList = orderListDOS.stream().filter(orderListDO -> StrUtil.equals(orderListDO.getComboId(), entity.getPackId().toString())).toList();
            entity.setSoldCopies(Long.valueOf(orderListDOList.size()));
            entity.setUnsoldCopies(entity.getTotalCopiesDistributed() - entity.getSoldCopies());
            entity.setSalesRate(NumberUtil.mul(NumberUtil.div(entity.getSoldCopies(), entity.getTotalCopiesDistributed()), 100));
            entity.setTotalSalesAmount(orderListDOList.stream().map(item -> NumberUtil.toBigDecimal(item.getAmt())).reduce(BigDecimal.ZERO, BigDecimal::add));
        });
        return list;
    }

    @Override
    public TableDataInfo<PackageSalesDataForSinglePackageVO> getPackageSalesDataForSinglePackage(PackageSalesDataForSinglePackageDTO packStatisticsReq) {
        MarCouponPackShop marCouponPackShop = marCouponPackShopService.findById(packStatisticsReq.getPackId());
        MachineDO machineDO = BeanUtil.toBean(packStatisticsReq, MachineDO.class);
        PageUtils.startPage();
        List<MachineDO> machineDOS = machineService.listMachine(machineDO);
        long total = new PageInfo(machineDOS).getTotal();

        PackageSalesDataDTO packageSalesDataDTO = BeanUtil.toBean(packStatisticsReq, PackageSalesDataDTO.class);
        List<OrderListDO> orderListDOS = orderListService.listPackStatisticsByPackIds(packageSalesDataDTO, Collections.singletonList(packStatisticsReq.getPackId()));

        List<PackageSalesDataForSinglePackageVO> list = machineDOS.stream().map(entity -> {
            PackageSalesDataForSinglePackageVO packStatisticsVO = new PackageSalesDataForSinglePackageVO();
            packStatisticsVO.setPositionName(Optional.ofNullable(positionService.getById(entity.getPositionId()).getPositonName()).orElse(""));
            packStatisticsVO.setMachineId(entity.getMachineId());
            packStatisticsVO.setMachineName(entity.getMachineName());
            List<OrderListDO> collect = orderListDOS.stream().filter(item -> StrUtil.equals(item.getMachineId(), entity.getMachineId())).collect(Collectors.toList());
            packStatisticsVO.setSoldCopies(Long.valueOf(collect.size()));
            // 避免除以零的情况
            if (marCouponPackShop.getPackNum() == 0) {
                packStatisticsVO.setSoldCopiesRate(BigDecimal.ZERO);
            } else {
                packStatisticsVO.setSoldCopiesRate(NumberUtil.mul(NumberUtil.div(packStatisticsVO.getSoldCopies(), marCouponPackShop.getPackNum()), 100));
            }
            packStatisticsVO.setTotalSalesAmount(collect.stream().map(item -> NumberUtil.toBigDecimal(item.getAmt())).reduce(BigDecimal.ZERO, BigDecimal::add));
            return packStatisticsVO;
        }).toList();

        TableDataInfo<PackageSalesDataForSinglePackageVO> dataTable = PageUtils.getDataTable(list);
        dataTable.setTotal(total);

        // 左下角求和
        PackageSalesDataForSinglePackageTotalVO totalVO = this.getPackageSalesDataForSinglePackageTotalVO(packStatisticsReq);
        dataTable.setData(totalVO);
        return dataTable;
    }

    @Override
    public PackageSalesDataForSinglePackageTotalVO getPackageSalesDataForSinglePackageTotalVO(PackageSalesDataForSinglePackageDTO packStatisticsReq) {
        MarCouponPackShop marCouponPackShop = marCouponPackShopService.findById(packStatisticsReq.getPackId());
        MachineDO machineDO = BeanUtil.toBean(packStatisticsReq, MachineDO.class);
        List<MachineDO> machineDOS = machineService.listMachine(machineDO);

        PackageSalesDataDTO packageSalesDataDTO = BeanUtil.toBean(packStatisticsReq, PackageSalesDataDTO.class);
        List<OrderListDO> orderListDOS = orderListService.listPackStatisticsByPackIds(packageSalesDataDTO, Collections.singletonList(packStatisticsReq.getPackId()));

        List<PackageSalesDataForSinglePackageVO> list = machineDOS.stream().map(entity -> {
            PackageSalesDataForSinglePackageVO packStatisticsVO = new PackageSalesDataForSinglePackageVO();
            packStatisticsVO.setPositionName(Optional.ofNullable(positionService.getById(entity.getPositionId()).getPositonName()).orElse(""));
            packStatisticsVO.setMachineId(entity.getMachineId());
            packStatisticsVO.setMachineName(entity.getMachineName());
            List<OrderListDO> collect = orderListDOS.stream().filter(item -> StrUtil.equals(item.getMachineId(), entity.getMachineId())).collect(Collectors.toList());
            packStatisticsVO.setSoldCopies(Long.valueOf(collect.size()));
            // 避免除以零的情况
            if (marCouponPackShop.getPackNum() == 0) {
                packStatisticsVO.setSoldCopiesRate(BigDecimal.ZERO);
            } else {
                packStatisticsVO.setSoldCopiesRate(NumberUtil.mul(NumberUtil.div(packStatisticsVO.getSoldCopies(), marCouponPackShop.getPackNum()), 100));
            }
            packStatisticsVO.setTotalSalesAmount(collect.stream().map(item -> NumberUtil.toBigDecimal(item.getAmt())).reduce(BigDecimal.ZERO, BigDecimal::add));
            return packStatisticsVO;
        }).toList();

        PackageSalesDataForSinglePackageTotalVO totalVO = new PackageSalesDataForSinglePackageTotalVO();
        Long soldCopies = list.stream().map(PackageSalesDataForSinglePackageVO::getSoldCopies).reduce(Long::sum).orElse(0L);
        BigDecimal soldCopiesRate = list.stream().map(PackageSalesDataForSinglePackageVO::getSoldCopiesRate).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totalSalesAmount = list.stream().map(PackageSalesDataForSinglePackageVO::getTotalSalesAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        totalVO.setSoldCopies(soldCopies);
        totalVO.setSoldCopiesRate(soldCopiesRate);
        totalVO.setTotalSalesAmount(totalSalesAmount);
        return totalVO;
    }

    @Override
    public UserLayerOverviewVO getUserLayerOverview(UserLayerDTO userLayerDTO) {
        UserLayerOverviewVO userLayerOverviewVO = new UserLayerOverviewVO();
        // 累计用户数，手机号唯一项的计数（不跟筛选时间走）
        userLayerOverviewVO.setTotalUser(orderListService.countUserMobileAll(userLayerDTO));
        // 下单用户数，单位时间内下单手机号唯一项的计数
        userLayerOverviewVO.setOrderUser(orderListService.countUserMobileByDate(userLayerDTO));
        // 新用户数，该日对比历史最新出现的手机号
        userLayerOverviewVO.setNewUser(this.countUserLayerOverviewNewUser(userLayerDTO));
        return userLayerOverviewVO;
    }

    @Override
    public Integer countUserLayerOverviewNewUser(UserLayerDTO userLayerDTO) {
        UserLayerDTO bean = BeanUtil.toBean(userLayerDTO, UserLayerDTO.class);
        // 获取该日下单手机号
        List<OrderListDO> orderListDOS = orderListService.listUserMobile(bean);
        List<String> userMobile = orderListDOS.stream().filter(Objects::nonNull).map(OrderListDO::getUserMobile).filter(Objects::nonNull).toList();
        int size = userMobile.size();
        if (size == 0) {
            return 0;
        }

        bean.setEndDate(bean.getStartDate());
        bean.setStartDate(null);
        List<OrderListDO> orderListDOS1 = orderListService.listNewUserMobile(bean, userMobile);
        List<String> userMobile1 = orderListDOS1.stream().filter(Objects::nonNull).map(OrderListDO::getUserMobile).filter(Objects::nonNull).toList();

        List<String> userMobile2 = CollUtil.subtractToList(userMobile, userMobile1);
        if (CollUtil.isEmpty(userMobile2)){
            return 0;
        }
        List<OrderListDO> orderListDOS2 = orderListService.listFirstUserMobile(bean, userMobile2);
        List<OrderListDO> collect = orderListDOS2.stream().filter(item -> {
            if (Objects.nonNull(bean.getAreaId())) {
                return StrUtil.equals(item.getAreaId(), bean.getAreaId());
            }
            return true;
        }).filter(item -> {
            if (Objects.nonNull(bean.getRouteId())) {
                return StrUtil.equals(item.getRouteId(), bean.getRouteId());
            }
            return true;
        }).filter(item -> {
            if (Objects.nonNull(bean.getPositionId())) {
                return StrUtil.equals(item.getPositionId(), bean.getPositionId());
            }
            return true;
        }).filter(item -> {
            if (Objects.nonNull(bean.getMachineId())) {
                return StrUtil.equals(item.getMachineId(), bean.getMachineId());
            }
            return true;
        }).filter(item -> {
            if (Objects.nonNull(bean.getCityName())) {
                return StrUtil.equals(item.getCityName(), bean.getCityName());
            }
            return true;
        }).collect(Collectors.toList());
        return collect.size();
    }

    @Override
    public List<OrderListDO> listUserLayerOverviewNewUser(UserLayerTotalUserDTO userLayerDTO) {
        UserLayerDTO bean = BeanUtil.toBean(userLayerDTO, UserLayerDTO.class);
        // 获取该日下单手机号
        List<OrderListDO> orderListDOS = orderListService.listUserMobile(bean);
        List<String> userMobile = orderListDOS.stream().filter(Objects::nonNull).map(OrderListDO::getUserMobile).filter(Objects::nonNull).toList();
        int size = userMobile.size();
        if (size == 0) {
            return Collections.emptyList();
        }

        bean.setEndDate(bean.getStartDate());
        bean.setStartDate(null);
        List<OrderListDO> orderListDOS1 = orderListService.listNewUserMobile(bean, userMobile);
        List<String> userMobile1 = orderListDOS1.stream().filter(Objects::nonNull).map(OrderListDO::getUserMobile).filter(Objects::nonNull).toList();

        List<String> userMobile2 = CollUtil.subtractToList(userMobile, userMobile1);
        if (CollUtil.isEmpty(userMobile2)){
            return Collections.emptyList();
        }
        List<OrderListDO> orderListDOS2 = orderListService.listFirstUserMobile(bean, userMobile2);
        List<OrderListDO> collect = orderListDOS2.stream().filter(item -> {
            if (Objects.nonNull(bean.getAreaId())) {
                return StrUtil.equals(item.getAreaId(), bean.getAreaId());
            }
            return true;
        }).filter(item -> {
            if (Objects.nonNull(bean.getRouteId())) {
                return StrUtil.equals(item.getRouteId(), bean.getRouteId());
            }
            return true;
        }).filter(item -> {
            if (Objects.nonNull(bean.getPositionId())) {
                return StrUtil.equals(item.getPositionId(), bean.getPositionId());
            }
            return true;
        }).filter(item -> {
            if (Objects.nonNull(bean.getMachineId())) {
                return StrUtil.equals(item.getMachineId(), bean.getMachineId());
            }
            return true;
        }).filter(item -> {
            if (Objects.nonNull(bean.getCityName())) {
                return StrUtil.equals(item.getCityName(), bean.getCityName());
            }
            return true;
        }).collect(Collectors.toList());


        return collect;
    }

    @Override
    public BigDecimal getUserLayerNewUserSequentialGrowth(Integer newUser, UserLayerDTO userLayerDTO) {
        UserLayerDTO bean = BeanUtil.toBean(userLayerDTO, UserLayerDTO.class);

        long betweenDay = DateUtil.betweenDay(bean.getStartDate(), bean.getEndDate(), true);
        bean.setStartDate(DateUtil.offsetDay(bean.getStartDate(), (int) -betweenDay));
        bean.setEndDate(DateUtil.offsetDay(bean.getEndDate(), (int) -betweenDay - 1));
        Integer i = this.countUserLayerOverviewNewUser(bean);

        if (i == 0) {
            return NumberUtil.mul(NumberUtil.toBigDecimal(newUser), 100);
        }
        BigDecimal div = NumberUtil.div(NumberUtil.sub(newUser, i), i);
        return NumberUtil.mul(div, 100);
    }

    @Override
    public BigDecimal getUserLayerRepurchaseRate(Integer totalUser, UserLayerDTO userLayerDTO) {
        UserLayerDTO bean = BeanUtil.toBean(userLayerDTO, UserLayerDTO.class);

        // 复购率 单位时间，购买两次及以上的用户数/有购买行为的总用户数
        Integer i = orderListService.countUserMobileCount2(userLayerDTO);
        if (i == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal div = NumberUtil.div(i, totalUser);
        return NumberUtil.mul(div, 100);
    }

    @Override
    public TableDataInfo<UserLayerTotalUserVO> getUserLayerTotalUserList(UserLayerTotalUserDTO userLayerTotalUserDTO) {
        PageUtils.startPage();
        List<UserLayerTotalUserVO> orderListDOS = orderListService.listUserLayerTotalUser(userLayerTotalUserDTO);
        long total = new PageInfo(orderListDOS).getTotal();
        TableDataInfo<UserLayerTotalUserVO> dataTable = PageUtils.getDataTable(orderListDOS);
        dataTable.setTotal(total);
        return dataTable;
    }

    @Override
    public List<UserLayerTotalUserVO> getUserLayerTotalUserListExport(UserLayerTotalUserDTO userLayerDTO) {
        List<UserLayerTotalUserVO> orderListDOS = orderListService.listUserLayerTotalUser(userLayerDTO);
        return orderListDOS;
    }


    @Override
    public TableDataInfo<UserLayerTotalUserVO> getUserLayerOrderUserList(UserLayerTotalUserDTO userLayerDTO) {
        PageUtils.startPage();
        List<UserLayerTotalUserVO> orderListDOS = orderListService.listUserLayerOrderUserList(userLayerDTO);
        long total = new PageInfo(orderListDOS).getTotal();
        TableDataInfo<UserLayerTotalUserVO> dataTable = PageUtils.getDataTable(orderListDOS);
        dataTable.setTotal(total);
        return dataTable;
    }

    @Override
    public List<UserLayerTotalUserVO> getUserLayerOrderUserListExport(UserLayerTotalUserDTO userLayerDTO) {
        List<UserLayerTotalUserVO> orderListDOS = orderListService.listUserLayerOrderUserList(userLayerDTO);
        return orderListDOS;
    }

    @Override
    public TableDataInfo<UserLayerTotalUserVO> getUserLayerNewUserList(UserLayerTotalUserDTO userLayerDTO) {
        List<OrderListDO> orderListDOS = this.listUserLayerOverviewNewUser(userLayerDTO);
        List<String> userMobiles = orderListDOS.stream().map(OrderListDO::getUserMobile).collect(Collectors.toList());

        PageUtils.startPage();
        List<Client> clients = clientService.listByUserLayerTotalUserDTO(userLayerDTO, userMobiles);
        long total = new PageInfo(clients).getTotal();

        List<UserLayerTotalUserVO> collect = clients.stream().map(item -> {
            UserLayerTotalUserVO userLayerTotalUserVO = new UserLayerTotalUserVO();
            userLayerTotalUserVO.setUserMobile(item.getMobile());
            userLayerTotalUserVO.setNickName(item.getNickName());
            return userLayerTotalUserVO;
        }).collect(Collectors.toList());

        TableDataInfo<UserLayerTotalUserVO> dataTable = PageUtils.getDataTable(collect);
        dataTable.setTotal(total);
        return dataTable;
    }

    @Override
    public List<UserLayerTotalUserVO> getUserLayerNewUserListExport(UserLayerTotalUserDTO userLayerDTO) {
        List<OrderListDO> orderListDOS = this.listUserLayerOverviewNewUser(userLayerDTO);
        List<String> userMobiles = orderListDOS.stream().map(OrderListDO::getUserMobile).collect(Collectors.toList());

        List<Client> clients = clientService.listByUserLayerTotalUserDTO(userLayerDTO, userMobiles);

        List<UserLayerTotalUserVO> collect = clients.stream().map(item -> {
            UserLayerTotalUserVO userLayerTotalUserVO = new UserLayerTotalUserVO();
            userLayerTotalUserVO.setUserMobile(item.getMobile());
            userLayerTotalUserVO.setNickName(item.getNickName());
            return userLayerTotalUserVO;
        }).collect(Collectors.toList());

        return collect;
    }

    @Override
    public TableDataInfo<UserLayerVO> getUserLayerList(UserLayerDTO userLayerDTO) {

        PageUtils.startPage();
        List<PositionDO> positionDOS = positionService.userLayerList(userLayerDTO);
        long total = new PageInfo(positionDOS).getTotal();

        List<String> positionIds = positionDOS.stream().map(PositionDO::getPositionId).toList();
        List<MachineDO> machineDOS = machineService.listMachineByPositionIds(positionIds);
        Map<String, List<MachineDO>> machineMapByPositionId = machineDOS.stream().collect(Collectors.groupingBy(MachineDO::getPositionId));


        List<UserLayerVO> list = positionDOS.stream().map(entity -> {
            UserLayerVO userLayerVO = new UserLayerVO();
            userLayerVO.setPositionId(entity.getPositionId());
            userLayerVO.setPositionName(entity.getPositonName());
            userLayerVO.setMachineNum(machineMapByPositionId.getOrDefault(entity.getPositionId(), Collections.emptyList()).size());

            userLayerDTO.setPositionId(entity.getPositionId());
            UserLayerOverviewVO userLayerOverview = this.getUserLayerOverview(userLayerDTO);
            userLayerVO.setTotalUser(userLayerOverview.getTotalUser());
            userLayerVO.setOrderUser(userLayerOverview.getOrderUser());
            userLayerVO.setNewUser(userLayerOverview.getNewUser());

            userLayerVO.setNewUserSequentialGrowth(this.getUserLayerNewUserSequentialGrowth(userLayerVO.getNewUser(), userLayerDTO));
            // 避免除以零的情况
            if (userLayerVO.getTotalUser() == 0) {
                userLayerVO.setNewUserRatio(BigDecimal.ZERO);
            } else {
                userLayerVO.setNewUserRatio(NumberUtil.mul(NumberUtil.div(userLayerVO.getNewUser(), userLayerVO.getTotalUser()), 100));
            }
            userLayerVO.setRepurchaseRate(this.getUserLayerRepurchaseRate(userLayerVO.getTotalUser(), userLayerDTO));

            return userLayerVO;
        }).toList();


        TableDataInfo<UserLayerVO> dataTable = PageUtils.getDataTable(list);
        dataTable.setTotal(total);
        return dataTable;
    }

    @Override
    public List<UserLayerVO> getUserLayerListExport(UserLayerDTO userLayerDTO) {

        List<PositionDO> positionDOS = positionService.userLayerList(userLayerDTO);

        List<String> positionIds = positionDOS.stream().map(PositionDO::getPositionId).toList();
        List<MachineDO> machineDOS = machineService.listMachineByPositionIds(positionIds);
        Map<String, List<MachineDO>> machineMapByPositionId = machineDOS.stream().collect(Collectors.groupingBy(MachineDO::getPositionId));


        List<UserLayerVO> list = positionDOS.stream().map(entity -> {
            UserLayerVO userLayerVO = new UserLayerVO();
            userLayerVO.setPositionId(entity.getPositionId());
            userLayerVO.setPositionName(entity.getPositonName());
            userLayerVO.setMachineNum(machineMapByPositionId.getOrDefault(entity.getPositionId(), Collections.emptyList()).size());

            userLayerDTO.setPositionId(entity.getPositionId());
            UserLayerOverviewVO userLayerOverview = this.getUserLayerOverview(userLayerDTO);
            userLayerVO.setTotalUser(userLayerOverview.getTotalUser());
            userLayerVO.setOrderUser(userLayerOverview.getOrderUser());
            userLayerVO.setNewUser(userLayerOverview.getNewUser());

            userLayerVO.setNewUserSequentialGrowth(this.getUserLayerNewUserSequentialGrowth(userLayerVO.getNewUser(), userLayerDTO));
            // 避免除以零的情况
            if (userLayerVO.getTotalUser() == 0) {
                userLayerVO.setNewUserRatio(BigDecimal.ZERO);
            } else {
                userLayerVO.setNewUserRatio(NumberUtil.mul(NumberUtil.div(userLayerVO.getNewUser(), userLayerVO.getTotalUser()), 100));
            }
            userLayerVO.setRepurchaseRate(this.getUserLayerRepurchaseRate(userLayerVO.getTotalUser(), userLayerDTO));

            return userLayerVO;
        }).toList();

        return list;
    }


    @Override
    public TableDataInfo<UserLayerMachineVO> getUserLayerMachineList(UserLayerDTO userLayerDTO) {
        MachineDO machineDO = BeanUtil.toBean(userLayerDTO, MachineDO.class);
        PageUtils.startPage();
        List<MachineDO> machineDOS = machineService.listMachine(machineDO);
        long total = new PageInfo(machineDOS).getTotal();

        List<UserLayerMachineVO> list = machineDOS.stream().map(entity -> {
            UserLayerMachineVO userLayerMachineVO = new UserLayerMachineVO();
            userLayerMachineVO.setMachineName(entity.getMachineName());
            userLayerMachineVO.setMachineSn(entity.getMachineSn());

            userLayerDTO.setMachineId(entity.getMachineId());
            UserLayerOverviewVO userLayerOverview = this.getUserLayerOverview(userLayerDTO);
            userLayerMachineVO.setTotalUser(userLayerOverview.getTotalUser());
            userLayerMachineVO.setOrderUser(userLayerOverview.getOrderUser());
            userLayerMachineVO.setNewUser(userLayerOverview.getNewUser());

            userLayerMachineVO.setNewUserSequentialGrowth(this.getUserLayerNewUserSequentialGrowth(userLayerMachineVO.getNewUser(), userLayerDTO));
            // 避免除以零的情况
            if (userLayerMachineVO.getTotalUser() == 0) {
                userLayerMachineVO.setNewUserRatio(BigDecimal.ZERO);
            } else {
                userLayerMachineVO.setNewUserRatio(NumberUtil.mul(NumberUtil.div(userLayerMachineVO.getNewUser(), userLayerMachineVO.getTotalUser()), 100));
            }
            userLayerMachineVO.setRepurchaseRate(this.getUserLayerRepurchaseRate(userLayerMachineVO.getTotalUser(), userLayerDTO));

            return userLayerMachineVO;
        }).toList();


        TableDataInfo<UserLayerMachineVO> dataTable = PageUtils.getDataTable(list);
        dataTable.setTotal(total);
        return dataTable;
    }

    @Override
    public TableDataInfo<ComboSalesVO> getComboSalesList(ComboSalesDTO comboSalesDTO) {

        PageUtils.startPage();
        List<ComboSalesDO> comboSalesDOList = deviceComboPlanNumService.getComboSalesList(comboSalesDTO);
        long total = new PageInfo(comboSalesDOList).getTotal();

        List<ComboSalesVO> list = comboSalesDOList.stream().map(entity -> {
            ComboSalesVO comboSalesVO = BeanUtil.toBean(entity, ComboSalesVO.class);
            // 避免除以零的情况
            if (comboSalesVO.getShelfCount() == 0) {
                comboSalesVO.setAvgSaleNum(BigDecimal.ZERO);
            } else {
                comboSalesVO.setAvgSaleNum(NumberUtil.div(comboSalesVO.getTotalSaleNum(), comboSalesVO.getShelfCount()));
            }

            // 避免除以零的情况
            if (entity.getShelfTotalSales() == 0) {
                comboSalesVO.setRepurchaseRate(BigDecimal.ZERO);
            } else {
                comboSalesVO.setRepurchaseRate(NumberUtil.mul(NumberUtil.div(comboSalesVO.getTotalSaleNum(), entity.getShelfTotalSales()), 100));
            }
            return comboSalesVO;
        }).toList();

        TableDataInfo<ComboSalesVO> dataTable = PageUtils.getDataTable(list);
        dataTable.setTotal(total);
        return dataTable;
    }

    @Override
    public List<ComboSalesVO> getComboSalesListExport(ComboSalesDTO comboSalesDTO) {

        List<ComboSalesDO> comboSalesDOList = deviceComboPlanNumService.getComboSalesList(comboSalesDTO);

        List<ComboSalesVO> list = comboSalesDOList.stream().map(entity -> {
            ComboSalesVO comboSalesVO = BeanUtil.toBean(entity, ComboSalesVO.class);
            // 避免除以零的情况
            if (comboSalesVO.getShelfCount() == 0) {
                comboSalesVO.setAvgSaleNum(BigDecimal.ZERO);
            } else {
                comboSalesVO.setAvgSaleNum(NumberUtil.div(comboSalesVO.getTotalSaleNum(), comboSalesVO.getShelfCount()));
            }

            // 避免除以零的情况
            if (entity.getShelfTotalSales() == 0) {
                comboSalesVO.setRepurchaseRate(BigDecimal.ZERO);
            } else {
                comboSalesVO.setRepurchaseRate(NumberUtil.mul(NumberUtil.div(comboSalesVO.getTotalSaleNum(), entity.getShelfTotalSales()), 100));
            }
            return comboSalesVO;
        }).toList();

        return list;
    }

    @Override
    public TableDataInfo<ComboSalesPositionVO> getComboSalesPositionList(ComboSalesPositionDTO comboSalesDTO) {

        PageUtils.startPage();
        List<ComboSalesPositionVO> comboSalesPositionList = deviceComboPlanNumService.getComboSalesPositionList(comboSalesDTO);
        long total = new PageInfo(comboSalesPositionList).getTotal();

        for (ComboSalesPositionVO comboSalesPositionVO : comboSalesPositionList) {
            // 避免除以零的情况
            if (comboSalesPositionVO.getShelfCount() == 0) {
                comboSalesPositionVO.setRepurchaseRate(BigDecimal.ZERO);
            } else {
                comboSalesPositionVO.setRepurchaseRate(NumberUtil.mul(NumberUtil.div(comboSalesPositionVO.getSaleNum(), comboSalesPositionVO.getShelfCount()), 100));
            }
        }
        // 总计
        List<ComboSalesPositionVO> comboSalesPositionList2 = deviceComboPlanNumService.getComboSalesPositionList(comboSalesDTO);
        ComboSalesPositionTotalVO comboSalesPositionTotalVO = new ComboSalesPositionTotalVO();
        Integer shelfCount = comboSalesPositionList2.stream().map(ComboSalesPositionVO::getShelfCount).reduce(Integer::sum).orElse(0);
        Integer saleNum = comboSalesPositionList2.stream().map(ComboSalesPositionVO::getSaleNum).reduce(Integer::sum).orElse(0);
        comboSalesPositionTotalVO.setShelfCount(shelfCount);
        comboSalesPositionTotalVO.setSaleNum(saleNum);

        TableDataInfo<ComboSalesPositionVO> dataTable = PageUtils.getDataTable(comboSalesPositionList);
        dataTable.setTotal(total);
        dataTable.setData(comboSalesPositionTotalVO);

        return dataTable;
    }
}
